package com.hb.config;

import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import java.util.Arrays;

/**
 * 除了直接声明 MongoClient bean 和 MongoTemplate bean，我们还可以让配置类扩展 AbstractMongoClientConfiguration 并重载 getDatabaseName() 和 mongoClient() 方法。
 * 这个新的配置类与程 MongoDBConfig 配置类的功能是相同的，只不过在篇幅上更加简洁。最为显著的区别在于这个配置中没有直接声明 MongoTemplate bean，当然它还是会被隐式地创建。我们在这
 * 里重载了 getDatabaseName() 方法来提供数据库的名称。mongoClient() 方法依然会创建一个 MongoClient 的实例，因为它会抛出 Exception，所以我们可以直接使用 MongoClient，而
 * 不必再使用 MongoFactoryBean 了。
 */
@Configuration
@EnableMongoRepositories(basePackages = "com.hb.repository")
public class OtherMongoDBConfig extends AbstractMongoClientConfiguration {
    @Override
    public MongoClient mongoClient() {
        return super.mongoClient();
    }

    @Override
    public String getDatabaseName() {
        return "OrdersDB";
    }

    public com.mongodb.MongoClient oldMongoClient() {
        // 如果 MongoDB 服务器运行在其他的机器上，那么可以在创建 MongoClient 的时候进行指定
        return new com.mongodb.MongoClient("mongodbserver");
        // 另外，MongoDB 服务器有可能监听的端口并不是默认的 27017。如果是这样的话，在创建 MongoClient 的时候，还需要指定端口
        // return new com.mongodb.MongoClient("mongodbserver", 37017);
    }

    @Autowired
    private Environment env;

    /**
     * 如果 MongoDB 服务器运行在生产配置上，我认为你可能还启用了认证功能。在这种情况下，为了访问数据库，我们还需要提供应用的凭证。
     * @return
     */
    public com.mongodb.MongoClient credentialMongoClient() {
        MongoCredential credential = MongoCredential.createCredential(
                env.getProperty("mongo.username"),
                "OrdersDB",
                env.getProperty("mongo.password").toCharArray());
        // 为了访问需要认证的 MongoDB 服务器，MongoClient 在实例化的时候必须要有一个 MongoCredential 的列表
        return new com.mongodb.MongoClient(new ServerAddress("localhost", 37017), Arrays.asList(credential));
    }
}
